# coding: utf-8

from django.conf import settings
from django.db import models
import mptt
from mptt.managers import TreeManager
import os
import re


def get_template_choices():
    GET_TITLE = re.compile(r'^{#\s*title\s*("|\')?(.*)("|\')?\s*#}$')
    choices = []
    for t_dir in settings.TEMPLATE_DIRS:
        template_dir = os.path.join(t_dir, 'pages')
        root_len = len(template_dir.split(os.sep))
        for path, _, files in os.walk(template_dir):
            rel_path = os.sep.join(path.split(os.sep)[root_len:])
            for f in files:
                if f.endswith('.html'):
                    rel_file = os.path.join(rel_path, f)
                    title = ""
                    fl = open(os.path.join(path, f), 'r')
                    title = fl.readline()
                    m = GET_TITLE.match(title)
                    if m:
                        title = "%s (%s)" % (m.group(2), rel_file)
                    else:
                        title = rel_file
                    fl.close()
                    choices.append((rel_file, title))

    choices = sorted(choices, key=lambda x: x[1])

    return choices



mptt_options = dict(parent_attr='parent',
                    left_attr='left', right_attr='right',
                    tree_id_attr='tree_id', level_attr='level')

class StructureNodeManager(TreeManager):
    def menu_visible(self):
        return self.get_query_set().filter(menu_visible=True)
    
    def get_by_path(self, path):
        bits = [b for b in path.split('/') if b]
        while len(bits):
            try:
                return StructureNode.objects.get(path=u'/%s/' % '/'.join(bits))
            except StructureNode.DoesNotExist:
                pass
            bits.pop()
            
        try:
            return StructureNode.objects.get(path=u'/')
        except StructureNode.DoesNotExist:
            return None



class StructureNode(models.Model):

    slug = models.SlugField(u'системное имя', max_length=100, blank=True)
    title = models.CharField(u'заголовок страницы', max_length=200)
    menu = models.CharField(u'навигация', max_length=200,
                            help_text=u'название пункта меню')

    subtitle = models.CharField(u'под заголовок страницы', max_length=200, blank=True, default="")

    menu_ico = models.CharField(u'Иконка', max_length=55, blank=True, default="")
    menu_ico_only = models.BooleanField(u"только иконка", default=False)

    menu_visible = models.BooleanField(u'в навигации', default=True,
                            help_text=u'отображать эту страницу в меню навигации')

    template = models.CharField(u'шаблон', max_length=100, choices=get_template_choices(), default='default.html')

    teaser = models.TextField(u'анонс', blank=True)
    content = models.TextField(u'текст', blank=True)
    
    gallery = models.ForeignKey('structure.Album', verbose_name=u'галерея', blank=True, null=True)

    redirect_url = models.CharField(u'ссылка для редиректа', blank=True, max_length=1000, default="")

    path = models.CharField(max_length=1000, editable=False, unique=True)
    parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
    objects = StructureNodeManager()

    class Meta:
        ordering = ('left', 'right')
        verbose_name = u'страница'
        verbose_name_plural = u'страницы'

    def __unicode__(self):
        return self.title

    def menu_visible_children(self):
        return self.children.filter(menu_visible=True)

    def update_path(self):
        node, parts = self, [self.slug, '']
        while node.parent:
            parts.insert(0, node.parent.slug)
            node = node.parent 
        self.path = '/'.join(parts)
    
    def save(self, force_insert=False, force_update=False):
        self.update_path()
        super(StructureNode, self).save(force_insert, force_update)
        for child in self.get_children():
            child.save()
            
    def get_absolute_url(self):
        return self.path
    
    def get_template(self):
        return 'pages/%s' % self.template
    
    def get_menu(self):
        return self.menu or self.title

    def get_full_title(self):
        ret = []
        for node in self.get_ancestors(True):
            if node.level > 2:
                ret.append(node.title)
        return u" - ".join(ret)

    @property    
    def fields(self):
        if not hasattr(self, '_fields'):
            self._fields = {}
            for field in StructureNodeExtendField.objects.filter(structure_node__in=self.get_ancestors(False, True)):
                self._fields[field.name] = field.value
        return self._fields

    @property    
    def self_fields(self):
        if not hasattr(self, '_self_fields'):
            self._self_fields = {}
            for field in StructureNodeExtendField.objects.filter(structure_node=self):
                self._self_fields[field.name] = field.value
        return self._self_fields

mptt.register(StructureNode, **mptt_options)



class StructureNodeExtendFieldManager(models.Manager):
    def get_by_name(self, name):
        return self.get(name=name)


class StructureNodeExtendField(models.Model):
    structure_node = models.ForeignKey(StructureNode, related_name='extend_fields')
    name = models.CharField(u'имя', max_length=200)
    value = models.CharField(u'содержимое', max_length=1024)
    
    objects = StructureNodeExtendFieldManager()
    
    class Meta:
        unique_together = ('structure_node', 'name')
        verbose_name = u'дополнительное поле'
        verbose_name_plural = u'дополнительные поля'
    
    def __unicode__(self):
        return self.name

class Album(models.Model):
    title = models.CharField(u'название', max_length=200)
    description = models.TextField(u'описание', blank=True)
    weight = models.SmallIntegerField(u'порядок', default=0)
    cover = models.ImageField(u'обложка', upload_to='uploads/', blank=True)
    
    class Meta:
        ordering = ('weight',)
        verbose_name = u'альбом'
        verbose_name_plural = u'альбомы'
        
    def __unicode__(self):
        return self.title

class Photo(models.Model):
    album = models.ForeignKey(Album)
    photo = models.ImageField(u'фотография', upload_to='uploads/')
    weight = models.SmallIntegerField(u'порядок', default=0)
    is_main = models.BooleanField(u'выводить на главную', default=False)
    
    class Meta:
        ordering = ('weight',)
        verbose_name = u'фотография'
        verbose_name_plural = u'фотографии'
